#ifndef 	 xTextureStage_h_h_h_h_h
#define  xTextureStage_h_h_h_h_h

#include "XDefine.h"
#include "xTexture.h"

namespace XE
{



	enum xTextureOp
	{
		// Control
		XTOP_DISABLE              = 1,      // disables stage
		XTOP_SELECTARG1           = 2,      // the default
		XTOP_SELECTARG2           = 3,

		// Modulate
		XTOP_MODULATE             = 4,      // multiply args together
		XTOP_MODULATE2X           = 5,      // multiply and  1 bit
		XTOP_MODULATE4X           = 6,      // multiply and  2 bits

		// Add
		XTOP_ADD                  =  7,   // add arguments together
		XTOP_ADDSIGNED            =  8,   // add with -0.5 bias
		XTOP_ADDSIGNED2X          =  9,   // as above but left  1 bit
		XTOP_SUBTRACT             = 10,   // Arg1 - Arg2, with no saturation
		XTOP_ADDSMOOTH            = 11,   // add 2 args, subtract product
		// Arg1 + Arg2 - Arg1*Arg2
		// = Arg1 + (1-Arg1)*Arg2

		// Linear alpha blend: Arg1*(Alpha) + Arg2*(1-Alpha)
		XTOP_BLENDDIFFUSEALPHA    = 12, // iterated alpha
		XTOP_BLENDTEXTUREALPHA    = 13, // texture alpha
		XTOP_BLENDFACTORALPHA     = 14, // alpha from D3DRS_TEXTUREFACTOR

		// Linear alpha blend with pre-multiplied arg1 input: Arg1 + Arg2*(1-Alpha)
		XTOP_BLENDTEXTUREALPHAPM  = 15, // texture alpha
		XTOP_BLENDCURRENTALPHA    = 16, // by alpha of current color

		// Specular mapping
		XTOP_PREMODULATE            = 17,     // modulate with next texture before use
		XTOP_MODULATEALPHA_ADDCOLOR = 18,     // Arg1.RGB + Arg1.A*Arg2.RGB
		// COLOROP only
		XTOP_MODULATECOLOR_ADDALPHA = 19,     // Arg1.RGB*Arg2.RGB + Arg1.A
		// COLOROP only
		XTOP_MODULATEINVALPHA_ADDCOLOR = 20,  // (1-Arg1.A)*Arg2.RGB + Arg1.RGB
		// COLOROP only
		XTOP_MODULATEINVCOLOR_ADDALPHA = 21,  // (1-Arg1.RGB)*Arg2.RGB + Arg1.A
		// COLOROP only

		// Bump mapping
		XTOP_BUMPENVMAP           = 22, // per pixel env map perturbation
		XTOP_BUMPENVMAPLUMINANCE  = 23, // with luminance channel

		// This can do either diffuse or specular bump mapping with correct input.
		// Performs the function (Arg1.R*Arg2.R + Arg1.G*Arg2.G + Arg1.B*Arg2.B)
		// where each component has been scaled and offset to make it signed.
		// The result is replicated into all four (including alpha) channels.
		// This is a valid COLOROP only.
		XTOP_DOTPRODUCT3          = 24,

		// Triadic ops
		XTOP_MULTIPLYADD          = 25, // Arg0 + Arg1*Arg2
		XTOP_LERP                 = 26, // (Arg0)*Arg1 + (1-Arg0)*Arg2

		XTOP_FORCE_DWORD = 0x7fffffff,

	};


	enum TextureOpArgument
	{
		XTA_SELECTMASK       =  0x0000000f , // mask for arg selector
		XTA_DIFFUSE          =  0x00000000,  // select diffuse color (read only)
		XTA_CURRENT          =  0x00000001 , // select stage destination register (read/write)
		XTA_TEXTURE          =  0x00000002  ,// select texture color (read only)
		XTA_TFACTOR          =  0x00000003 , // select D3DRS_TEXTUREFACTOR (read only)
		XTA_SPECULAR         =  0x00000004  ,// select specular color (read only)
		XTA_TEMP             =  0x00000005  ,// select temporary register color (read/write)
		XTA_CONSTANT         =  0x00000006  ,// select texture stage constant
		XTA_COMPLEMENT       =  0x00000010 , // take 1.0 - x (read modifier)
		XTA_ALPHAREPLICATE   =  0x00000020,  // replicate alpha to color components (read modifier)

	};


	typedef enum xTextureAddressMode
	{
		XTADDRESS_WRAP = 1,
		XTADDRESS_MIRROR = 2,
		XTADDRESS_CLAMP = 3,
		XTADDRESS_BORDER = 4,
		XTADDRESS_MIRRORONCE = 5,
		XTADDRESS_FORCE_DWORD = 0x7fffffff,
	};

                
	typedef enum  xTextureFileType
	{
	    XTEXF_NONE = 0,
		XTEXF_POINT = 1,
		XTEXF_LINEAR = 2,
		XTEXF_ANISOTROPIC = 3,
		XTEXF_PYRAMIDALQUAD = 6,
		XTEXF_GAUSSIANQUAD = 7,
		XTEXF_CONVOLUTIONMONO = 8,
		XTEXF_FORCE_DWORD = 0x7fffffff,
	} ;






	class xTextureStage
	{
	public:

		xTextureStage();
		~xTextureStage();

		void SetTexture(xTexture* ptexture){m_pTexture = ptexture;}

		xTexture* GetTexture()const  {return m_pTexture;}

		void SetTextureColorOP(xTextureOp top,TextureOpArgument a1,TextureOpArgument a2);

		void SetTextureAlphaOP(xTextureOp top,TextureOpArgument a1,TextureOpArgument a2);

		void SetTextureAddressMode(xTextureAddressMode u,xTextureAddressMode v,xTextureAddressMode w);

		void SetBorderColor(const xColor& col){m_BorderCol = col;}
		const xColor& GetBorderColor()const {return m_BorderCol;}

		void SetMagFilter(xTextureFileType filetype){ m_Magfilter = filetype;}

		xTextureFileType GetMagFilter()const {return m_Magfilter;}

		void SetMinFilter(xTextureFileType filetype){m_Minfilter =filetype;}
		xTextureFileType GetMinFilter()const {return m_Minfilter;}



       xTexture* m_pTexture;

	   xTextureOp m_ColorOP;
	   TextureOpArgument m_ColorAg1;
	   TextureOpArgument m_ColorAg2;


	   xTextureOp m_AlphaOP;
	   TextureOpArgument m_AlphaAg1;
	   TextureOpArgument m_AlphaAg2;

	   xTextureAddressMode m_addres[3];//---UVW
	   xColor m_BorderCol;

	   xTextureFileType m_Magfilter;
	   xTextureFileType m_Minfilter;



	 


	};

}










#endif